package com.project.seckill.rocketmq;

import com.alibaba.fastjson.JSONObject;
import com.project.seckill.entity.Order;
import com.project.seckill.entity.ProductStockLog;
import com.project.seckill.service.OrderService;
import com.project.seckill.service.ProductService;
import com.project.seckill.service.ProductStockLogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RocketMQTransactionListener
public class LocalTransactionListenerImp implements RocketMQLocalTransactionListener {

    @Autowired
    private OrderService orderService;

    @Autowired
    private ProductStockLogService productStockLogService;

    /**
     * 执行本地事务
     *
     * @param message
     * @param obj
     * @return
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object obj) {
        try {
            String tags = message.getHeaders().get("rocketmq_TAGS").toString();
            if ("create_stock".equals(tags)) {
                return this.createOrder(message, obj);
            } else {
                return RocketMQLocalTransactionState.UNKNOWN;
            }
        }catch (Exception e){
            log.info("执行本地事务发生错误" + e);
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }

    private RocketMQLocalTransactionState createOrder(Message message, Object obj) {
        JSONObject param = (JSONObject) obj;
        Integer userId = (Integer) param.get("userId");
        Long productId = (Long) param.get("productId");
        Integer num = (Integer) param.get("num");
        String productStockLogId =  param.getString("productStockLogId");

        try {
            Order order = orderService.createOrder(userId,productId,num,productStockLogId);
            return RocketMQLocalTransactionState.COMMIT;
        }catch (Exception e) {
            productStockLogService.updateProductStockLogStatus(productStockLogId,3);
            return RocketMQLocalTransactionState.ROLLBACK;
        }

    }

    /**
     * 检查本地事务
     * @param message
     * @return
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        try {
            String tags = message.getHeaders().get("rocketmq_TAGS").toString();
            if ("create_stock".equals(tags)) {
                return this.checkStockStatus(message);
            } else {
                return RocketMQLocalTransactionState.UNKNOWN;
            }
        }catch (Exception e){
            log.info("检查本地事务发生错误" + e);
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }

    private RocketMQLocalTransactionState checkStockStatus(Message message) {
        JSONObject object = JSONObject.parseObject(new String((byte[]) message.getPayload()));
        String productStockLogId = object.getString("productStockLogId");
        ProductStockLog productStockLog = productStockLogService.getById(productStockLogId);
        if (productStockLog == null){
            return RocketMQLocalTransactionState.ROLLBACK;
        }else if(productStockLog.getStatus() == 0){
            return RocketMQLocalTransactionState.UNKNOWN;
        }else if(productStockLog.getStatus() == 1){
            return RocketMQLocalTransactionState.COMMIT;
        }else{
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }
}
